除了 Deployment 和 ReplicaSet 外,另外介紹 DeamonSet 與 StatefulSet 這兩個資源。
確保在叢集中每個 node 上都會有一個 pod replica。當叢集中有新的 node 加入時,daemonset controller 會主動為該 node 新增一個 pod;當 node 被刪除時,其新增的 pod 也會被刪除。
如同 deployment 與 replicaSet 一樣,刪除時其建立的 pod 也會跟著被移除。
另外像是每個 node 上會有一個 kube-proxy,這個就是使用 daemonset 建立的 pods。還有之前某篇使用到的 weave-net 的 network plugin 同樣也是使用 daemonset 建立。
DaemonSet 與 ReplicaSet 很像,差別在於 DaemonSet 沒有 replica
屬性。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: monitoring-daemon
spec:
selector:
matchLabels:
app: monitoring-agent
template:
metadata:
labels:
app: app: monitoring-agent
spec:
containers:
- name: monitoring-agent
image: app: monitoring-agent
使用 elasticsearch image 建立 daemonset。
kubectl create deployment elasticsearch --image=registry.k8s.io/fluentd-elasticsearch:1.20 --dry-run=client -o yaml > fluentd.yaml
--dry-run=client
:將要建立的物件輸出檢視、而不實際執行。修改 kind
為 DaemonSet
,刪除 replica
與 strategy
。
vi fluent.yaml
建立。
kubectl create -f fluentd.yaml
daemonset.apps/elasticsearch created
查看。
kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
elasticsearch 1 1 1 1 1 <none> 3s
kubectl get po
NAME READY STATUS RESTARTS AGE
elasticsearch-tqcnh 1/1 Running 0 14s
Deployment 是用來管理無狀態(Stateless)的應用程式,而 statefulset 則是用來管理有狀態(stateful)的應用程式(elastic)或是資料庫(MySQL 或 mongoDB)。
例如:http 是無狀態的 protocol,指的是每次從 client 發出的 request 都是獨立的,這一次的 request 無法得知上一次 request 的內容和資訊。
一般來說微服務的架構較適合管理無狀態的應用程式,有狀態的應用程式則會牽涉到「資料一致性」的問題,因此實務常會將資料庫架在叢集之外來避免前述問題。
StatefulSet 目的是在 scale up 或 scale down 時確保資料或資料庫的讀寫是一致的。
StatefulSet 會為每個建立的 pods 賦予一個獨立的 ID,當這個 pod 掛掉時 controller 會另外起一個新的 pod 並將該 ID 給新 pod 使用。賦予 ID 的用意是當有多個資料庫的 pod 會需要指定一個主要寫入的 pod,方便讓 controller 去識別。